Aspect-oriented component assembly - a case study in parallel software design

نویسندگان

  • Clemens Dangelmayr
  • Wolfgang Blochinger
چکیده

aspect BalancingBridgeTemplate { abstract pointcut i n s t a n t i a t i o n ( Object w) ; abstract pointcut handl ing ( Object w) ; after ( Object w) : i n s t a n t i a t i o n (w) { ba lance r . n o t i f y I n s t an t i a t i o n (w) ; } after ( Object w) : handl ing (w) { ba lancer . not i fyHand l ing (w) ; } } Listing 8. Aspect Template: Balancing Bridge. To integrate the balancing component with a distributed application, one must instantiate both pointcuts. This allows the balancing component to observe changes to the local workload status and to take necessary balancing actions. Figure 3 illustrates how all discussed techniques work together. In general, a number of equivalent pointcuts can be used to inject the same crosscutting functionality. For workload instantiation/handling we intercept instantiations of classes implementing the interface Node and calls to the method visit—as alternatives to intercepting Agenda+.append/Agenda+.extract. 3.2.4. Integrating Low-Level Functionality with Annotation Introduction As outlined in Section 3.1.2 advanced state space search algorithms often generate additional heuristic knowledge which must be exchanged between processors to increase efficiency. Thus, tools are required which allow to tag the specific execution points where this heuristic content is generated such that new heuristic information can be broadcast upon encounter. Tagging such execution points is a special case of a common requirement in the creation of complex systems: integrating low-level concerns like logging, persistence, or security. This can be accomplished using annotations. Section 3.2.7 further discusses the benefits of annotation-based approaches. Aspect-Oriented Concepts and Constructs. In Section 3.2.2, we discussed the use of introductions. Besides allowing to insert new fields and methods, they enable us to attach annotations. Calls to methods tagged this way can then be intercepted by pointcuts incorporating these annotations. Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls ASPECT-ORIENTED COMPONENT ASSEMBLY FOR PARALLELIZATION 13 Figure 4. Parallel Quicksort. Local Method Calls are Highlighted. Application. We illustrate the use of annotating join points on the example of propagating heuristic information—as an element of the client-part of the communication component. To declare method calls to be propagated, we attach annotations to dedicated methods. For our traveling salesperson example these are the methods setting newly found bounds (as specified in Listing 9). declare @method : void Bound . setValue (double ) : @Distr ibute ; Listing 9. Attached Annotation: Tagging Heuristic Knowledge. Propagating these method calls is then realized with after-advice (as illustrated in Listing 10). abstract aspect Heur i s t i cKnowledgeDis t r ibu t ion { abstract void propagate (RPC rpc ) ; after ( ) : ca l l ( @Distr ibute ∗ ∗ ( . . ) ) { propagate (new RPC( thisJoinPoint ) ) ; } }aspect Heur i s t i cKnowledgeDis t r ibu t ion { abstract void propagate (RPC rpc ) ; after ( ) : ca l l ( @Distr ibute ∗ ∗ ( . . ) ) { propagate (new RPC( thisJoinPoint ) ) ; } } Listing 10. Aspect Template: Heuristic Knowledge Distribution. 3.2.5. Non-intrusive Adaptation of Component Functionality with around-Advice Section 3.1.2 outlines how quicksort can be parallelized. Every processor executes the algorithm in Listing 1. However, instead of executing all calls to sort, different processors execute different subsets of all initiated calls. This is illustrated in Figure 4. In this version of parallel quicksort, different processors are responsible for different sub-ranges of the total sorting range (determined by subsequent choices of pivot elements). Thus, a non-intrusive technique which allows intercepting and possibly circumventing the execution of selected method calls is needed. Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls 14 C. DANGELMAYR AND W. BLOCHINGER Figure 5. Favorable vs. Unfavorable Problem Configuration. Aspect-Oriented Concepts and Constructs. Aspect-orientation allows us to non-intrusively redirect the inner control flow of arbitrary components. Here, we use the around -advice construct, which is able to intercept and circumvent the execution of selected statements. (In contrast to after-advice, around-advice is executed instead of the intercepted join point and not after it.) Application. Listing 11 shows an aspect template intercepting and circumventing calls to dedicated methods. Methods tagged with @Task are intercepted. The corresponding join point is then mapped to a processor. Only if this processor equals the local processor, the method call is executed with proceed(). abstract aspect TaskDisposit ionTemplate { abstract Proces sor mapToProcessor ( JoinPoint jo inPo in t ) ; void around ( ) : ca l l (@Task ∗ ∗ ( . . ) ) { i f ( mapToProcessor ( thisJoinPoint ) . equa l s ( l o c a lP r o c e s s o r ) ) proceed ( ) ; } }aspect TaskDisposit ionTemplate { abstract Proces sor mapToProcessor ( JoinPoint jo inPo in t ) ; void around ( ) : ca l l (@Task ∗ ∗ ( . . ) ) { i f ( mapToProcessor ( thisJoinPoint ) . equa l s ( l o c a lP r o c e s s o r ) ) proceed ( ) ; } } Listing 11. Aspect Template: Task Disposition. To instantiate this template, we tag sort(Range) and let mapToProcessor implement the mapping function illustrated in Figure 4. Now, every processor executes the same algorithm but only a subset of all initiated calls to sort. With the problem configuration illustrated in Figure 4, workload is distributed equally over participating processors. In general, workload balance between processors depends upon the subsequent selection of pivot elements. This is illustrated in Figure 5 for different problem configurations. Thus, in general, dynamic load balancing becomes additionally necessary. Prematurely idle processors request unsorted sub-ranges, corresponding to calls to sort, from non-idling processors. Here, Range objects represent exchangeable content (compare Section 3.2.3). By implementing BalancerCallback, we incorporate the delegation of sub-ranges into processor mapping, superposing the application-specific part illustrated in Figure 4. The application range of the around-advice construct is extremely wide, as it can be applied on every level (e.g. to intercept a high-level method) and is able to redirect the control flow of arbitrary software elements. Even a non-intrusive adaptation of the parallel platform, e.g. to cope with unreliability is possible as we discuss subsequently. Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls ASPECT-ORIENTED COMPONENT ASSEMBLY FOR PARALLELIZATION 15 Tackling Unreliability with Non-intrusive Behavior Adaptation. In some cases the functionality of one or more of the available components may be inadequate for a specific application or deployment scenario. Thus, an adaptation of the inner behavior of components becomes necessary. A typical example is dealing with high unreliability, e.g. prevailing in large, loosely coupled distributed systems where participating processors frequently join and leave. Often, unreliability cannot be tackled efficiently in a fully generic way, such that application specific measures become mandatory. In addition to generic fault tolerance measures (see Section 3.1.3), eager scheduling [36] can be an efficient way to tackle high probability of losses of tasks. The basic principle is to dynamically assign a task which is already scheduled (but yet uncompleted) to additional processors when its result is not delivered within a given time frame. To introduce this subaspect into the parallel platform, we intercept the lookup method for candidates for remote handling of the balancer component and add already distributed tasks to the list of potential candidates for remote execution (as illustrated in Listing 12). abstract aspect EagerSchedulingTemplate { abstract pointcut workload ( ) ; abstract Co l l e c t i on getDelegatedTasks ( ) ; Co l l e c t i on around ( ) : workload ( ) { Co l l e c t i on cand idate s = new LinkedList (proceed ( ) ) ; cand idat e s . addAll ( getDelegatedTasks ( ) ) ; return cand idat e s ; } }aspect EagerSchedulingTemplate { abstract pointcut workload ( ) ; abstract Co l l e c t i on getDelegatedTasks ( ) ; Co l l e c t i on around ( ) : workload ( ) { Co l l e c t i on cand idate s = new LinkedList (proceed ( ) ) ; cand idat e s . addAll ( getDelegatedTasks ( ) ) ; return cand idat e s ; } } Listing 12. Aspect Template: Eager Scheduling. While the method getDelegatedTasks retrieves tasks which are already scheduled, the abstract pointcut workload is used to intercept access to objects qualifying as candidates for workload exchange. In Listing 13, we instantiate the originally abstract pointcut to intercept read access to the field load of the LoadBalancer object. pointcut workload ( ) : get ( Co l l e c t i on LoadBalancer . load ) && withincode (void LoadBalancer . s e l e c tConten t ( ) ) ; Listing 13. Instantiated Pointcut: Workload Access. In highly volatile settings, processors going off-line should also try to minimize lost workload by sending back partially handled workload. In our state space search example, partially handled workload is constituted by unvisited nodes of a sub-tree, either still in the agenda or present as reference on another node. Here, the introduced recovery aspect requires to instantiate an abstract pointcut, whose advice collects these findings and sends them to their appropriate receivers. The employed parallel platform must contain join points qualifying for an instantiation of this abstract pointcut which are e.g. join points indicating an upcoming shutdown of the processor. In addition, the technique can be used to realize specific routing functionality to compensate the lack of direct communication channels. Here, we intercept the sending of messages in analogous manner. When the target processor of a message is not visible, the message is Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls 16 C. DANGELMAYR AND W. BLOCHINGER encapsulated in a special routing message, which is sent to a currently visible, randomly chosen processor. When this routing message arrives at the remote processor, it passes the original message to the communication subsystem. Re-routing is repeated until the message is finally delivered or a termination criterion applies. 3.2.6. Restructuring Control Flow with loop-Pointcuts Data decomposition requires partitioning data sets into disjunctive subsets, which can be handled in parallel. In most cases, this means partitioning control flow structured by forloops. In our matrix multiplication example as implemented in Listing 2 different iterations of the loop compute different elements of the result matrix/vector. Thus, we subdivide the loop range into partitions processed by different processors. Aspect-Oriented Concepts and Constructs. Aspect-oriented programming with AspectJ unfortunately still lacks the possibility to intercept single loop iterations on a structural level. In [26], the authors deal with this shortcoming. A loop-Pointcut is presented addressing this issue. However, in order to ensure broad applicability we restrict our approach to the common standards Java and AspectJ. Thus, we inject parallelism on a lower level and use around-Advice on workload-intensive parts of the loop body (similarly to constraining method execution as described in Section 3.2.5). Application. An aspect template similar to the one shown in Listing 11 is used to intercept parts of the loop body. For parallel matrix multiplication, we attach @Task to methods multiplying matrices with vectors (Matrix.multiply(Vector) in Listing 2), thus computing single rows of the result matrix. For method calls which are not executed the aroundadvice returns a proxy object. A generic implementation is employed for processor mapping (illustrated in Listing 14): every processor executes only every n-th method call (assuming n processors) starting with an offset represented by its index in an ordering over all processors. int index = 0 ; Proces sor mapToProcessor ( JoinPoint jo inPo in t ) { return p ro c e s s o r s . get ( index++ % proc e s s o r s . s i z e ( ) ) ; } Listing 14. Instantiated Method: Generic Processor Mapping. As we focus on irregularly distributed workload, we additionally use dynamic load balancing to distribute remaining method calls over idle processors. Here, matrix-vector-multiplications are handled as first-class-objects, implementing the command pattern [19]. 3.2.7. Summary and Discussion In the previous sections, we showed how aspect-oriented programming allows us to assemble all components without having to modify them. As our techniques require introspection of components, it is basically a glass-box approach [21]. In this section, we briefly recapitulate Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls ASPECT-ORIENTED COMPONENT ASSEMBLY FOR PARALLELIZATION 17 our use of the different aspect-oriented techniques, classifying them into dynamic and static crosscutting [31]. Dynamic Crosscutting. We use after -advice to non-intrusively inject internal state monitoring between components (compare Section 3.2.1). This forwarding of control comes always into play, when changes to an object must be passed on to structures dependent on this object. As opposed to after-advice, around -advice can be used to intercept and circumvent arbitrary method calls. Section 3.2.5 shows how to employ this construct to non-intrusively redirect the inner control flow of arbitrary components. To further decouple components, advice is incorporated into bridge templates (see Section 3.2.3). These are implemented using abstract aspects and abstract pointcuts. This approach decouples components and facilitates connecting varying implementations. By replacing the server-adapter, other platform components can be integrated. Just as new instantiations of the bridge template can integrate crosscutting functionality into different applications. Static Crosscutting. In Section 3.2.2, we showed how to allow components to manipulate internal state of other components. Here, we used introductions to provide for an adapter implementing a callback interface with corresponding get/set methods. As this adapter accesses private object state, we use a privileged aspect. With introductions, we are not only able to introduce additional methods or fields, but also to attach annotations to methods. In Section 3.2.4, we showed how to tag low-level crosscutting functionality this way. The main advantage of this approach is conciseness, since assembly code is here restricted to annotation introductions. These can be arranged arbitrarily, allowing for more freedom in decomposition and also enhance readability. Especially, this approach turns out to be effective for low-level functionality, where no parameter binding is required and many join points are intercepted. 3.3. Aspect-Oriented vs. Object-Oriented Component Assembly In this section we compare aspect-oriented and object-oriented approaches to component assembly in a qualitative manner. (A quantitative analysis is presented in Section 4.) In contrast to object-oriented programming, we do not have to impose artificial structures on our design, but can use appropriate and especially designed techniques and tools. We will see that with conventional object-oriented programming, one could at best fall back to the usual design patterns [19], to which these aspect-oriented techniques correspond to, while still having to manipulate and adapt the original code. Prime example for this is the conventional implementation of the observer pattern in comparison to the use of after -advice. Before discussing the different assembly issues, we describe how object-oriented programming prevents component immutability in component-based systems. Component Immutability. Inter-component communication in object-oriented component systems is traditionally restricted to interfaces (or ports), that are established when the components were implemented. Unfortunately, this seriously impairs subsequent integration of crosscutting concerns. If the constraint on the immutability of components holds (compare Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls 18 C. DANGELMAYR AND W. BLOCHINGER Section 3.1.3), the number of crosscutting concerns, that can be integrated, is considerably reduced. Basically these are limited to crosscutting concerns anticipated with appropriate hooks during the implementation of the component. Thus, to subsequently integrate non-anticipated crosscutting concerns we have to employ a white-box-approach [21] with component mutability. Monitoring of Internal State. To implement internal state monitoring, one would use the observer pattern [19]. This implies the modification of all classes where corresponding events occur, as these must now publish relevant status changes to observers. Besides having to change the original implementation, this can hardly be considered a native approach. In addition, it introduces redundancies, which are known to be error-prone. Furthermore, it reduces code quality as intrusive assembly impairs separation of concerns. Manipulating Internal State. To allow for the manipulation of internal component state, referenced by fields of constituting classes, one would use the adapter pattern [19]. However, if the corresponding fields are declared private and no suitable set/get methods are available, there is no possibility to access them without changing the original code. With aspect-oriented programming, however, we can separately specify appropriate adapters in aspects, preserving the original implementation and full reusability of accessed components. Although, when using a privileged aspect, the aspect-oriented approach softens the information hiding principle of object-oriented programming, this is crucial, as Java’s implementation of this principle is partially incompatible with multi-dimensional decomposition (see discussion on dominant decomposition in Section 2). For a non-intrusive adapter in object-oriented programming one would have to employ reflection (e.g. provided by the java.lang.reflect package [28]). However, reflection is a low-level technique outside the language scope and impacts performance considerably. Decoupling Components. To decouple components, we interconnect bridges (based on bridge templates) between components. Applying aspect-orientation enables us to keep the code of all assembled components untouched, even when actual crosscutting is required. All additional functionality can be coherently encapsulated in aspects, defined in their respective compilation units. Although the server-adapter may be used in a pure object-oriented approach as well, installing a bridge between both components would still require intrusive modification of the crosscut code. Integrating Low-Level Functionality. Pure Java allows also tagging low-level functionality with annotations. However, it does not permit to explicitly state where to insert them. Furthermore, to process this information we would have to use a form of reflection (see above). Adaptation of Functionality. As mentioned, the concrete deployment scenario sometimes requires adaptation of inner control flow of components. The advantage of employing aspectoriented programming is that instead of having to change the original implementation of components and probably impairing their usability or efficiency for other deployment scenarios, we can simply plug-in lightweight modifications if needed, while still being able to maintain and advance the original, generic component. Copyright c © 2000 John Wiley & Sons, Ltd. Softw. Pract. Exper. 2000; 00:1–7 Prepared using speauth.cls ASPECT-ORIENTED COMPONENT ASSEMBLY FOR PARALLELIZATION 19 Especially in this case an object-oriented approach would seriously impair the code quality of involved components, probably up to the point where a complete re-design would be favorable over the adaptation of existing components. A common approach in object-orientation is to extract and encapsulate insufficient functionality in strategy-objects (see strategy pattern [19]), allowing for their substitution with better suiting ones. 4. Quantitative Analysis In this section, we compare the discussed aspect-oriented and the object-oriented approach to component assembly quantitatively. We assemble parallel programs consisting of the different sequential applications described in Section 3.1.1 and the platform components described in Section 3.1.3. (As all exemplary applications feature a high degree of irregularity, dynamic load balancing is required in all cases, as well as fault tolerance and termination detection). We measure code quality metrics like cohesion or coupling where appropriate. Additionally, we conduct performance measurements for both approaches. We ensure comparability by using a direct and bijective mapping of aspect-oriented to object-oriented code, resulting in appropriate assembly issue/design pattern implementations for both cases. Specifically, we convert AspectJ aspects to Java classes by mapping advice to methods, which in turn are called from the join points the associated pointcut intercepts. For example, the object-oriented pendant of after -Advice applied to the execution of a certain method (after() : execution(..) {..}) consists of a call to the respective method (of the converted aspect) at the bottom of the intercepted method. The same applies for introduced methods.

برای دانلود رایگان متن کامل این مقاله و بیش از 32 میلیون مقاله دیگر ابتدا ثبت نام کنید

ثبت نام

اگر عضو سایت هستید لطفا وارد حساب کاربری خود شوید

منابع مشابه

A Component Assembly Approach Based On Aspect-Oriented Generative Domain Modeling

We present an approach towards automatic component assembly based on aspect-oriented generative domain modeling. It involves the lifecycle covering the component specification generation, and subsequent assembly of implementation components to produce the final software system. Aspect-oriented techniques are applied to capture the crosscutting concerns that emerge during the assembly process. S...

متن کامل

Identifying Similar Pattern of Potential Aspect Oriented Functionalities in Software Development Life Cycle

Aspect Aspect-oriented programming is known as a technique for modularizing crosscutting concerns. However, there are no clear rules to help detect and implement Aspects in the software development lifecycle. Consequently, class developers face changeability, parallel development and comprehensibility problems, because they must be aware of aspects whenever they develop or maintain a class. The...

متن کامل

Design Patterns with Aspects: A case study

This paper reports on a case study in which four programs were implemented in both aspect-oriented and object-oriented versions using four different design patterns. We report on our experiences with the use of these design patterns and the trade-offs that needed to be considered. Furthermore, we present additional evidence for a reduction of coupling through the use of aspect-oriented versions...

متن کامل

Extension Morphisms for CommUnity

Superpositions are useful relationships between programs or components in component based approaches to software development. We study the application of invasive superposition morphisms between components in the architecture design language CommUnity. This kind of morphism allows us to characterise component extension relationships, and in particular, serves an important purpose for enhancing ...

متن کامل

Comparing Aspect-Oriented and Component-Based design: A Quantitative Study

Although Aspect-Oriented Software Development (AOSD) has been a topic of research for more than ten years, there is still little empirical proof of its actual benefits. In particular, few empirical studies have been conducted to illustrate the value of aspect orientation in the earlier phases of the software life-cycle. To move towards filling this gap in the current state-of-the-art, we focus ...

متن کامل

An Investigation to Physical Aspects of Middle Area in Squares as a Useful Indicator for Designing Community-Oriented Urban Plazas (Case Study: Italian Piazzas of Campidoglio in Rome, Del Campo in Siena and San Marco in Venice)

Middle of squares, one of the components of physical aspect is considered as an appropriateindicator in designing successful urban squares, which consequently promotes visual quality. The present study aims todetermine how the above mentioned aspect was presented in the Middle-Ages and Renaissance within Italian squares.Considering the aim of the investigation, library studies as well as visual...

متن کامل

ذخیره در منابع من


  با ذخیره ی این منبع در منابع من، دسترسی به آن را برای استفاده های بعدی آسان تر کنید

عنوان ژورنال:
  • Softw., Pract. Exper.

دوره 39  شماره 

صفحات  -

تاریخ انتشار 2009